package com.zy.ems.common.jedis;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Redis客户端工具类。
 * 
 * @author Luffy
 * 
 */
public class JedisUtils {
    /**
     * Redis属性文件名
     */
    private final static String REDIS_PROPERTIES_FILE_NAME = "redis";

    /**
     * Redis服务列表属性名
     */
    private final static String REDIS_SERVER_LIST_NAME = "serverlist";

    /**
     * 缓存服务分隔符
     */
    private final static String SEPARATOR = ",";

    /**
     * 客户端
     */
    private static JedisCluster jedisCluster;

    static {
        ResourceBundle rb = ResourceBundle
                .getBundle(REDIS_PROPERTIES_FILE_NAME);
        String serverlist = rb.getString(REDIS_SERVER_LIST_NAME);
        Set<HostAndPort> nodes = new HashSet<HostAndPort>(getAddresses(serverlist));

        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大空闲连接数
        jedisPoolConfig.setMaxIdle(5);
        // 最大连接数
        jedisPoolConfig.setMaxTotal(1024);
        // 获取连接时的最大等待毫秒数
        jedisPoolConfig.setMaxWaitMillis(5000);
        // 在获取连接的时候检查有效性
        jedisPoolConfig.setTestOnBorrow(true);

        jedisCluster = new JedisCluster(nodes, jedisPoolConfig);

    }

    /**
     * 设置key<br/>
     *
     * @param key key
     * @param value 值
     * @author sunshine
     * @date 2016年1月26日 下午9:18:45
     */
    public static boolean set(String key, String value) {
        String result = jedisCluster.set(key, value);
        return result.toLowerCase().equals("ok");
    }

    /**
     * 设置key或增加key<br/>
     *
     * @param key key
     * @param value 值
     */
    public static Long incrBy(String key, Long value) {
        Long result = jedisCluster.incrBy(key, value);
        return result;
    }

    /**
     * 设置key<br/>
     *
     * @param key key
     * @param value 值
     * @param seconds 有效期
     * @return
     * @author sunshine
     * @date 2016年1月27日 下午5:14:03
     */
    public static boolean set(String key, String value, int seconds) {
        String result = jedisCluster.setex(key, seconds, value);
        return result.toLowerCase().equals("ok");
    }

    /**
     * 当key不存在时设置key，返回true，否则返回false<br/>
     *
     * @param key
     * @param value
     * @return
     * @author sunshine
     * @date 2016年1月27日 下午5:14:00
     */
    public static boolean setnx(String key, String value) {
        Long result = jedisCluster.setnx(key, value);
        return result == 1;
    }

    /**
     * 如果key存在则设置key的值为value，并且设置有效期为second，返回ture，否则返回false <br/>
     *
     * @param key
     * @param value
     * @param seconds
     * @return
     * @author sunshine
     * @date 2016年1月27日 下午5:13:56
     */
    public static boolean setnx(String key, String value, int seconds) {
        String result = jedisCluster.setex(key, seconds, value);
        return result.toLowerCase().equals("ok");
    }

    /**
     * key值追加value <br/>
     *
     * @param key
     * @param value
     * @return 字符的长度
     * @author sunshine
     * @date 2016年1月26日 下午11:09:00
     */
    public static Long append(String key, String value) {
        return jedisCluster.append(key, value);
    }

    /**
     * 设置hash<br/>
     *
     * @param key
     * @param hash
     * @author sunshine
     * @date 2016年1月26日 下午9:29:58
     */
    public static boolean hset(String key, Map<String, String> hash) {
        String result = jedisCluster.hmset(key, hash);
        return result.toLowerCase().equals("ok");
    }

    public static boolean hset(String key, Map<String, String> hash,
            int seconds) {
        String result = jedisCluster.hmset(key, hash);
        jedisCluster.expire(key, seconds);
        return result.toLowerCase().equals("ok");
    }

    /**
     * 获取key值<br/>
     *
     * @param key
     * @author sunshine
     * @date 2016年1月26日 下午9:18:56
     */
    public static String get(String key) {
        return jedisCluster.get(key);
    }

    /**
     * 获取hash值，一次可以获取多个 <br/>
     *
     * @param key
     * @param fields
     * @return
     * @author sunshine
     * @date 2016年1月26日 下午11:12:02
     */
    public static List<String> hget(String key, String... fields) {
        return jedisCluster.hmget(key, fields);
    }

    /**
     * 获取key对应的所有map数据<br/>
     *
     * @param key
     * @return
     * @author sunshine
     * @date 2016年1月26日 下午11:31:19
     */
    public static Map<String, String> hget(String key) {
        return jedisCluster.hgetAll(key);
    }

    /**
     * 判断key是否存在<br/>
     *
     * @param key
     * @return
     * @author sunshine
     * @date 2016年1月26日 下午9:18:30
     */
    public static boolean isExist(String key) {
        return jedisCluster.exists(key);
    }

    /**
     * 删除key对应的数据 <br/>
     *
     * @param key
     * @return
     * @author sunshine
     * @date 2016年1月27日 下午5:16:20
     */
    public static Long del(String key) {
        return jedisCluster.del(key);
    }

    /**
     * 批量设置缓存 <br/>
     *
     * @param keysvalues
     * @return
     * @author sunshine
     * @date 2016年3月30日 上午10:27:41
     */
    public String mset(final String... keysvalues) {
        return jedisCluster.mset(keysvalues);
    }

    /**
     * 更改key <br/>
     *
     * @param oldkey
     * @param newkey
     * @return
     * @author sunshine
     * @date 2016年3月30日 上午10:44:46
     */
    public String rename(String oldkey, String newkey) {
        return jedisCluster.rename(oldkey, newkey);
    }

    public Long sadd(String key, String... values) {
        return jedisCluster.sadd(key, values);
    }

    /**
     * 批量获取数据 <br/>
     *
     * @param keys
     * @return
     * @author sunshine
     * @date 2016年3月30日 上午10:27:30
     */
    public List<String> mget(final String... keys) {
        return jedisCluster.mget(keys);
    }

    /**
     * Split a string in the form of "host:port host2:port" into a Set.
     * 
     * @param servers
     * @return
     */
    private static Set<HostAndPort> getAddresses(String servers) {
        if (servers == null) {
            throw new NullPointerException("Null host list");
        }
        if (servers.trim().equals("")) {
            throw new IllegalArgumentException("No hosts in list: " + servers);
        }
        servers = servers.trim();
        String[] hosts = servers.split(SEPARATOR);
        Set<HostAndPort> set = new HashSet<HostAndPort>(hosts.length);
        for (String host : hosts) {
            String[] hostAndPort = host.split(":");
            set.add(new HostAndPort(hostAndPort[0],
                    Integer.valueOf(hostAndPort[1])));
        }
        return set;
    }

}
